<%#
kind: registration
name: Global Registration
model: ProvisioningTemplate
description: |
  The registration template used to render OS agnostic script that any host can use to register to
  this Foreman instance. It is rendered as a response in the registration API endpoint. The resulting
  script contains instructions to prepare the machine for registration, to create a new Host record in Foreman,
  and to fetch and run the host specific initial configuration script. The initial script is rendered based
  on the template of host_init_config kind.
-%>
#!/bin/sh

# Make sure, all command output can be parsed (e.g. from subscription-manager)
export LC_ALL=C LANG=C
<%
    headers = ["--header 'Authorization: Bearer #{@auth_token}'"]
    activation_keys = [(@hostgroup.params['kt_activation_keys'] if @hostgroup), @activation_keys].compact.join(',')
-%>

# Rendered with following template parameters:
<%= "# User: [#{@user.login}]" if @user -%>
<%= "\n# Organization: [#{@organization.name}]" if @organization -%>
<%= "\n# Location: [#{@location.name}]" if @location -%>
<%= "\n# Host group: [#{@hostgroup.title}]" if @hostgroup -%>
<%= "\n# Operating system: [#{@operatingsystem}]" if @operatingsystem -%>
<%= "\n# Setup Insights: [#{@setup_insights}]" unless @setup_insights.nil? -%>
<%= "\n# Setup remote execution: [#{@setup_remote_execution}]" unless @setup_remote_execution.nil? -%>
<%= "\n# Setup remote execution pull: [#{@setup_remote_execution_pull}]" unless @setup_remote_execution_pull.nil? -%>
<%= "\n# Remote execution interface: [#{@remote_execution_interface}]" if @remote_execution_interface.present? -%>
<%= "\n# Packages: [#{@packages}]" if @packages.present? -%>
<%= "\n# Update packages: [#{@update_packages}]" unless @update_packages.nil? -%>
<%= "\n# Repository data: [#{@repo_data}]" if @repo_data.present? -%>
<%= "\n# Force: [#{@force}]" unless @force.nil? -%>
<%= "\n# Ignore subman errors: [#{@ignore_subman_errors}]" unless @ignore_subman_errors.nil? -%>
<%= "\n# Set up container certs: [#{@setup_container_registry_certs}]" unless @setup_container_registry_certs.nil? -%>
<%= "\n# Lifecycle environment id: [#{@lifecycle_environment_id}]" if @lifecycle_environment_id.present? -%>
<%= "\n# Activation keys: [#{activation_keys}]" if activation_keys.present? -%>
<%= "\n# Download utility: [#{@download_utility}]" unless @download_utility.nil? -%>


if ! [ $(id -u) = 0 ]; then
  echo "Please run as root"
  exit 1
fi

# Select package manager for the OS (sets the $PKG_MANAGER* variables)
<%= snippet 'pkg_manager' %>

SSL_CA_CERT=$(mktemp)
cat << EOF > $SSL_CA_CERT
<%= foreman_server_ca_cert %>
EOF

cleanup_and_exit() {
  rm -f $SSL_CA_CERT
  exit $1
}

<%= snippet_if_exists('before_registration') -%>

<% unless @repo_data.blank? -%>
<% index = 0 %>
<% @repo_data.each do |repo, repo_gpg_key_url| -%>
echo '#'
echo '# Adding repository'
echo '#'

<% index += 1 %>
if [ x$PKG_MANAGER = xdnf -o x$PKG_MANAGER = xyum -o x$PKG_MANAGER = xzypper ]; then
  cat << EOF > /tmp/foreman_registration.repo
[foreman_register<%= index %>]
name=foreman_register<%= index %>
baseurl=<%= shell_escape repo %>
enabled=1
type=rpm-md
EOF
<% if repo_gpg_key_url.present? -%>
  echo gpgcheck=1 >> /tmp/foreman_registration.repo
  echo gpgkey=<%= shell_escape repo_gpg_key_url %> >> /tmp/foreman_registration.repo
<% else -%>
  echo gpgcheck=0 >> /tmp/foreman_registration.repo
<% end -%>
  if [ x$PKG_MANAGER = xdnf -o x$PKG_MANAGER = xyum ]; then
    mv -f /tmp/foreman_registration.repo /etc/yum.repos.d/foreman_registration<%= index %>.repo
    echo "Building yum metadata cache, this may take a few minutes"
    $PKG_MANAGER makecache
  else
    REPO_OPTIONS=""
    <% if repo_gpg_key_url.present? -%>
    <%= generate_web_request(utility: @download_utility, url: shell_escape(repo_gpg_key_url)) %> >/tmp/repo_gpg.key
    rpm --import /tmp/repo_gpg.key
    rm -f /tmp/repo_gpg.key
    REPO_OPTIONS='--gpgcheck-allow-unsigned-repo'
    <% end -%>
    zypper --quiet --non-interactive addrepo $REPO_OPTIONS /tmp/foreman_registration.repo
  fi
elif [ -f /etc/debian_version ]; then
  <%= save_to_file("/etc/apt/sources.list.d/foreman_registration#{index}.list", repo) %>
<% if repo_gpg_key_url.present? -%>
<%# "apt 1.2.35" on Ubuntu 16.04 does not support storing GPG public keys in "/etc/apt/trusted.gpg.d/" in ASCII format -%>
  if [ "$(. /etc/os-release ; echo "$VERSION_ID")" = "16.04" ]; then
    $PKG_MANAGER_INSTALL ca-certificates gnupg
    <%= indent(4, skip1: true) { generate_web_request(utility: @download_utility, url: shell_escape(repo_gpg_key_url)) } %> | gpg --dearmor > /etc/apt/trusted.gpg.d/client<%= index %>.gpg
  else
    $PKG_MANAGER_INSTALL ca-certificates
    <%= indent(4, skip1: true) { generate_web_request(utility: @download_utility, url: shell_escape(repo_gpg_key_url), output_file: "/etc/apt/trusted.gpg.d/client#{index}.asc") } %>
  fi
<% end -%>
  apt-get update

else
  echo "Unsupported operating system, can't add repository."
  cleanup_and_exit 1
fi
<% end -%>
<% end -%>

register_host() {
<%
  params = ["host[name]=$(hostname --fqdn)"]
  params << "host[build]=false"
  params << "host[managed]=false"
  params << "host[organization_id]=#{@organization.id}" if @organization
  params << "host[location_id]=#{@location.id}" if @location
  params << "host[hostgroup_id]=#{@hostgroup.id}" if @hostgroup
  params << "host[operatingsystem_id]=#{@operatingsystem.id}" if @operatingsystem
  params << "host[interfaces_attributes][0][identifier]=#{shell_escape(@remote_execution_interface)}" if @remote_execution_interface.present?
  params << "setup_insights=#{@setup_insights}" unless @setup_insights.nil?
  params << "setup_remote_execution=#{@setup_remote_execution}" unless @setup_remote_execution.nil?
  params << "remote_execution_interface=#{shell_escape(@remote_execution_interface)}" if @remote_execution_interface.present?
  params << "packages=#{shell_escape(@packages)}" if @packages.present?
  params << "update_packages=#{@update_packages}" unless @update_packages.nil?
-%>
  <%= indent(2, skip1: true) { generate_web_request(utility: @download_utility, url: @registration_url, ssl_ca_cert: "$SSL_CA_CERT", output_file: "/root/registration_host_init.sh", headers: headers, params: params) } %>
}

echo "#"
echo "# Running registration"
echo "#"

<% if plugin_present?('katello') && activation_keys.present? -%>
register_katello_host(){
<%
  params = ["uuid=$UUID"]
  params << "host[build]=false"
  params << "host[organization_id]=#{@organization.id}" if @organization
  params << "host[location_id]=#{@location.id}" if @location
  params << "host[hostgroup_id]=#{@hostgroup.id}" if @hostgroup
  params << "host[lifecycle_environment_id]=#{@lifecycle_environment_id}" if @lifecycle_environment_id.present?
  params << "setup_insights=#{@setup_insights}" unless @setup_insights.nil?
  params << "setup_remote_execution=#{@setup_remote_execution}" unless @setup_remote_execution.nil?
  params << "remote_execution_interface=#{shell_escape(@remote_execution_interface)}" if @remote_execution_interface.present?
  params << "setup_remote_execution_pull=#{@setup_remote_execution_pull}" unless @setup_remote_execution_pull.nil?
  params << "packages=#{shell_escape(@packages)}" if @packages.present?
  params << "update_packages=#{@update_packages}" unless @update_packages.nil?
-%>
  UUID=$(subscription-manager identity | grep --max-count 1 --only-matching '\([[:xdigit:]]\{8\}-[[:xdigit:]]\{4\}-[[:xdigit:]]\{4\}-[[:xdigit:]]\{4\}-[[:xdigit:]]\{12\}\)')
  <%= indent(2, skip1: true) { generate_web_request(utility: @download_utility, url: @registration_url, ssl_ca_cert: "$KATELLO_SERVER_CA_CERT", output_file: "/root/registration_host_init.sh", headers: headers, params: params) } %>
}

# Set up subscription-manager
<%= snippet("subscription_manager_setup", variables: { subman_setup_scenario: 'registration' }).strip -%>

subscription-manager register \
  --org='<%= @organization.label if @organization %>' \
  --activationkey='<%= activation_keys %>' || <%= truthy?(@ignore_subman_errors) ? 'true' : 'cleanup_and_exit 1' %>
<% end -%>

# Update / create the host record in Foreman and fetch the host initial configuration script
<%= plugin_present?('katello') ? "register_katello_host" : "register_host" %>

curl_status=$?
if [ $curl_status -ne 0 ]; then
  echo "Failed to fetch the host initialization script."
  echo "Please see the logs for more information."
  cleanup_and_exit $curl_status
fi

bash /root/registration_host_init.sh
init_conf_status=$?

if [ $init_conf_status -ne 0 ]; then
  echo "Host initialization script failed, see the logs for more information."
  echo "You can access the script source by running 'cat /root/registration_host_init.sh'"
  cleanup_and_exit $init_conf_status
fi

<% if truthy?(@setup_container_registry_certs) -%>
<%= snippet('container_certs_setup') -%>
<% end -%>
<%= snippet_if_exists('after_registration') -%>

cleanup_and_exit
